#ifndef COMMON_H
#define COMMON_H
#include <vector>
#include <complex>
using namespace std;
const double dErest=938.2723;
//#define REAL(z,i) ((z)[2*(i)])
//#define IMAG(z,i) ((z)[2*(i)+1])
template <typename valType>
void VectorToArray(std::vector<valType>* vInput,valType* vOutput)
{
    for(std::size_t i=0;i!=vInput->size();i++)
	vOutput[i]=(*vInput)[i];
};
template <typename valType>
void VectorToArray2D(std::vector<std::vector<valType>* >* vInput,valType* vOutput)
{
    for(std::size_t i=0;i!=vInput->size();i++)
    {
	for(std::size_t j=0;j!=(*vInput)[i]->size();j++)
	{
	    vOutput[i*j+j]=(*(*vInput)[i])[j];
	    //vOutput[i][j]=(*(*vInput)[i])[j];
	}
    }
};
template <typename valType>
void VectorToArray2Dx(std::vector<std::vector<valType>* >* vInput,valType** vOutput)
{
//    vector<valType> vTmp; 
    valType* vTmp; 
    for(std::size_t i=0;i!=vInput->size();i++)
    {
    VectorToArray(vInput[i],vTmp);
    (*vOutput)[i]=vTmp;
    }
};
//void zpTozt(vector<vector<double> > ,double ,double );
//void zpTozt(vector<vector<double> > *vvdIn,double dFreq,double _dGam=1)
void zpTozt(vector<vector<double> > ,double);
void zpTozt(vector<vector<double> > *vvdIn,double dFreq)
//从xp、yp、phi、W 到xt\yt\zt的转化
//假设i=0的一行储存的是同步粒子，横向是beam坐标系，相位、能量是每个粒子的实际值
//产生的坐标是beam坐标系下的
{ 
  double dWaveL=clight/dFreq/1e6;
  double dBetaS,dGamS;
//    if(_dGam==1) dGamS=_dGam;              
//    else dGamS=(*vvdIn)[0][5]/dErest+1;
    dGamS=(*vvdIn)[0][5]/dErest+1;
    dBetaS=sqrt(1-1/dGamS/dGamS);
  for(int i=1;i<vvdIn->size();i++)
  {
    //下面一行暂时不用，也就是纵向的phi暂时不变成t
//    (*vvdIn)[i][4]=((*vvdIn)[i][4]-(*vvdIn)[0][4])/360/dGamS*dBetaS*dWaveL*100;  // 100是把单位变成cm
    (*vvdIn)[i][5]=((*vvdIn)[i][5]-(*vvdIn)[0][5])/dBetaS/dGamS/dGamS/dGamS/dErest;   
    (*vvdIn)[i][5]=((*vvdIn)[i][5]-dBetaS)/(1-(*vvdIn)[i][5]*dBetaS)*clight*1e-4; 
    //the goal of 1e-4 here is to change the unit of clight to cm/us
    (*vvdIn)[i][1]=(*vvdIn)[i][1]*(*vvdIn)[i][5];  //the unit here is cm/us
    (*vvdIn)[i][3]=(*vvdIn)[i][3]*(*vvdIn)[i][5];
  }
  //需要重新设置同步粒子的值吗？
//  vvdIn[0][0]=0; vvdIn[0][2]=0;vvdIn[0][0]=0;
}
void ztTozp(vector<vector<double> > *vvdIn,double dFreq)
{
  double dWaveL=clight/dFreq/1e6;
  double dBetaS,dGamS;
  dGamS=(*vvdIn)[0][5]/dErest+1;
  dBetaS=sqrt(1-1/dGamS/dGamS);
  for(int i=1;i<vvdIn->size();i++)
  {
    (*vvdIn)[i][1]=(*vvdIn)[i][1]/(*vvdIn)[i][5];  //the unit here is cm/us
    (*vvdIn)[i][3]=(*vvdIn)[i][3]/(*vvdIn)[i][5];
    //下面一行暂时不用，也就是纵向的phi暂时不变成t
//    (*vvdIn)[i][4]=(*vvdIn)[0][4]+((*vvdIn)[i][4])*360*dGamS/dBetaS/dWaveL;
    (*vvdIn)[i][5]=((*vvdIn)[i][5]+dBetaS*clight*1e-4)/(1+(*vvdIn)[i][5]*dBetaS/clight*1e4)/clight*1e4; 
    (*vvdIn)[i][5]=(*vvdIn)[i][5]*dBetaS*dGamS*dGamS*dGamS*dErest+(*vvdIn)[0][5];   
  }

}    

void outPut(vector<vector<double> > * vvd,string str,int col1,int col2) //输出vvd的第i to j列
{
  ofstream ofile(str.c_str());
  if(!ofile)
    std::cout<<"can't open the "<<str<<" file"<<endl;
  for(int i=0;i<vvd->size();i++)
  {
    for(int j=col1;j<=col2;j++)
      ofile<<(*vvd)[i][j]<<" ";
    ofile<<endl;
  }
  /*
     int iflag=0;
     cout<<"whether plot the filedata with gunplot? 0 no,1 yes "<<<endl;
     cin>>iflag;
     if(iflag==1)
     cout<<"wait for...., the results saved at "<<str<<".eps"<<endl;
     ofile.close();
     ofile.open("draw.gun",ios::noreplace|ios::in|ios::out)
   */
  ofile.close();
}
#endif








